/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "底层绘图框架.h"

#include "intern/Vulkan/buffer/Vk缓存.h"
#include "intern/Vulkan/buffer/Vk图像.h"
#include "intern/Vulkan/Vulkan框架.h"
#include "intern/Vulkan/线管/着色器.h"
#include "intern/Vulkan/线管/线管.h"
#include "intern/Vulkan/光追后端.h"

//#include "intern/OpenGL/S_OpenGL框架.h"
#include "intern/DirectX/DirectX框架.h"
//#include "intern/缓存/S_顶点数组管理.h"
#include <future>
#include <set>

#include "面/Surface.h"


#define FENCE_TIMEOUT 100000000





static E_绘图API	g_apiName = E_绘图API::E_DirectX12;
static S_绘图框架*	g_绘图框架 = 0;


static std::set<S_协处理设备*>	g_物理设备;


S_绘图框架 * f_创建绘图框架(E_绘图API apiName) {
	g_apiName = apiName;

	if (apiName == E_绘图API::E_Vulkan) {

		S_VK框架* f = 0;
		//g_绘图框架 = new S_VK框架();
		std::future<void> f1 = std::async(std::launch::async, [&]() {
			
		});
		f1.wait();
		g_绘图框架 = new S_VK框架();
		return g_绘图框架;
		//g_绘图框架 = new S_VK框架();
	}
	else if (apiName == E_绘图API::E_DirectX12) {
		g_绘图框架 = new S_DirectX3D绘图框架();
	}


	return g_绘图框架;

}




/*S_设备环境 f_创建协处理器设备(uint32 物理设备, E_设备类型 类型, E_绘图API apiName) {
	//S_协处理设备* dev = (S_协处理设备*)malloc(sizeof(S_协处理设备));
	S_设备环境 ctx;
	ctx.m_Type = E_绘图API::E_Vulkan;
	ctx.m_物理设备 = g_绘图框架->f_取物理设备(物理设备);
	
	switch (类型) {
		case E_设备类型::e_绘图设备:
			ctx.m_逻辑设备 = g_绘图框架->f_创建图形逻辑设备(ctx.m_物理设备);
			break;
		case E_设备类型::e_计算设备:
			ctx.m_逻辑设备 = g_绘图框架->f_创建计算逻辑设备(ctx.m_物理设备);
			break;
	}

	g_绘图框架->f_创建命令缓存池(ctx.m_逻辑设备);
	g_绘图框架->f_创建命令缓存(ctx.m_逻辑设备, 0);
	g_绘图框架->f_创建同步围栏(ctx.m_逻辑设备);
	
	return ctx;
}*/

void* f_draw_创建绘图设备(S_设备环境& dev) {
	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)malloc(sizeof(S_绘图设备配置));
	S_物理设备属性* prop = (S_物理设备属性*)dev.m_物理设备.pNext;
	dev.m_绘图设备配置 = 绘图设备配置;

	绘图设备配置->m_设备 = (VkDevice)(dev.m_逻辑设备.设备);
	绘图设备配置->m_物理设备 = (VkPhysicalDevice)(dev.m_物理设备.设备);
	绘图设备配置->交换链列队家族Offset = dev.m_逻辑设备.ID;
	绘图设备配置->绘图列队家族Offset = dev.m_逻辑设备.ID;

	绘图设备配置->m_设备属性 = prop->m_设备属性;
	绘图设备配置->m_内存属性 = prop->m_内存属性;

	绘图设备配置->m_命令开始信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;//给定结构体类型
	绘图设备配置->m_命令开始信息.pNext = NULL;//自定义数据的指针
	绘图设备配置->m_命令开始信息.flags = 0;//描述使用标志
	绘图设备配置->m_命令开始信息.pInheritanceInfo = NULL;//命令缓冲继承信息

	绘图设备配置->m_当前帧ID = 0;
	绘图设备配置->m_列队ID = 0;

	绘图设备配置->m_图形列队 = (VkQueue*)calloc(10, sizeof(VkQueue));
	for (uint8 i = 0; i < 10; ++i) {
		vkGetDeviceQueue(绘图设备配置->m_设备, 绘图设备配置->绘图列队家族Offset, i, &(绘图设备配置->m_图形列队[i]));
	}



	f_vk创建命令缓存池(绘图设备配置);
	绘图设备配置->m_命令缓存 = f_vk创建命令缓存(绘图设备配置, 1);
	f_vk创建同步围栏(绘图设备配置);


	f_vkFrame_初始化光追函数指针(绘图设备配置);
	
	return 绘图设备配置;
}

void f_draw_销毁绘图设备(void* 绘图设备) {
	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)绘图设备;

	f_vk销毁命令缓存(绘图设备配置, 绘图设备配置->m_命令缓存);

	free(绘图设备配置->m_图形列队);
	free(绘图设备配置);
}






E_绘图API f_get后端框架名称() {
	return g_apiName;
}

void * f_get设备()
{
	return g_绘图框架->f_get设备();
}

void * f_get命令列表() {
	return g_绘图框架->f_get命令列表();
}

void * f_get环境() {
	return g_绘图框架->f_get环境();
}

/*S_着色* f_create着色(S_设备环境& ctx, std::vector<S_着色器加载参数> paths) {
	S_Vk着色* shader = new S_Vk着色((VkDevice&)(ctx.m_逻辑设备.设备), paths.size(), "shader_n1");
	for (uint32 i = 0; i < paths.size(); ++i) {
		shader->f_从文件载入着色器(paths[i].path, paths[i].阶段, i);
	}
	shader->f_build着色参数布局(1);
	return shader;
}*/

S_着色* f_create着色(S_设备环境& ctx, S_线管创建配置 ini) {
	S_Vk着色* shader = new S_Vk着色((VkDevice&)(ctx.m_逻辑设备.设备), ini.m_Paths.size(), "shader_n1");
	for (uint32 i = 0; i < ini.m_Paths.size(); ++i) {
		shader->f_从文件载入着色器(ini.m_Paths[i].path, ini.m_Paths[i].阶段, i);
	}
	shader->f_init着色参数布局(ini);
	return shader;
}

S_线管* f_create线管(S_设备环境& ctx, S_着色& shader, const S_线管创建参数& 线管参数, std::string name) {
	S_Vk线管* pipeline = new S_Vk线管(ctx, name);
	pipeline->f_创建线管(线管参数, shader);
	return pipeline;
}

S_线管* f_Gpu_create计算线管(S_设备环境& ctx, S_着色& shader, std::string name) {
	S_Vk计算线管* pipeline = new S_Vk计算线管(ctx, name);
	S_线管创建参数 nul({});
	pipeline->f_创建线管(nul, shader);
	return pipeline;
}


S_线管* f_df_create光追管线(S_设备环境& ctx, const S_线管创建配置& 线管参数) {
	S_Vk着色* shader = new S_Vk着色((VkDevice&)(ctx.m_逻辑设备.设备), 线管参数.m_Paths.size(), "光追着色");
	for (uint32 i = 0; i < 线管参数.m_Paths.size(); ++i) {
		shader->f_从文件载入着色器(线管参数.m_Paths[i].path, 线管参数.m_Paths[i].阶段, i, true);
	}
	shader->f_initRT着色参数布局(线管参数);

	S_Vk光追线管* pl = new S_Vk光追线管(ctx, "光追管线");
	pl->f_创建线管(线管参数, *shader);
	pl->m_着色 = shader;

	return pl;
}

S_光追后端* f_df_create光追后端(S_设备环境& ctx, const S_线管创建配置& 线管参数) {
	C_Vk光追后端* b = new C_Vk光追后端(ctx);
	b->m_线管创建配置信息 = 线管参数;
	b->m_光追管线 = f_df_create光追管线(ctx, 线管参数);
	b->f_构建着色绑定列表();

	return b;
}

void f_df_销毁光追后端(S_光追后端* 光追后端) {
	delete 光追后端;
}

void f_df_光追后端_重构着色器(S_光追后端* rt) {
	//((S_Vk光追线管*)rt->m_后端_光追管线)->m_着色->f_从文件载入着色器(path, E_着色阶段::e_光追回调, i, true);
}






void f_push板载缓存(S_着色* shader, void* data, uint64 bitSize){
	S_Vk着色* s = dynamic_cast<S_Vk着色*>(shader);
	s->m_设备;
}

S_结构对象指针 f_gpu_创建参数布局(S_板载缓存* 渲染参数, uint32 binding, uint32 阶段分布) {
	VkDevice 设备 = (VkDevice)(渲染参数->m_Ctx.m_逻辑设备.设备);

	vector<VkDescriptorPoolSize>			描述池大小;

	VkDescriptorSetLayoutBinding lb{};
	lb.binding = binding;
	lb.descriptorCount = 1;
	lb.descriptorType = f_vk_get缓存布局类型(渲染参数->m_Type);
	lb.stageFlags = f_vk_get参数布局着色阶段(阶段分布);

	VkDescriptorPoolSize ps;
	ps.type = lb.descriptorType;
	ps.descriptorCount = 1;
	描述池大小.push_back(ps);


	VkDescriptorSetLayoutCreateInfo 布局创建信息 = {};
	布局创建信息.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
	布局创建信息.pNext = NULL;
	布局创建信息.bindingCount = 1;
	布局创建信息.pBindings = &lb;

	VkDescriptorSetLayout m_参数布局;
	if (vkCreateDescriptorSetLayout(设备, &布局创建信息, nullptr, &m_参数布局) != VK_SUCCESS) {
		throw std::runtime_error("创建 GPU参数资源布局失败");
	}


	VkDescriptorPoolCreateInfo 描述池创建信息 = {};
	描述池创建信息.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
	描述池创建信息.pNext = 0;
	描述池创建信息.maxSets = 32;
	描述池创建信息.poolSizeCount = 描述池大小.size();
	描述池创建信息.pPoolSizes = 描述池大小.data();

	VkDescriptorPool 参数池;
	auto res = vkCreateDescriptorPool(设备, &描述池创建信息, 0, &参数池);
	assert(res == VK_SUCCESS);

	

	VkDescriptorSetAllocateInfo m_描述集列表分配信息 = {};
	m_描述集列表分配信息.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
	m_描述集列表分配信息.pNext = 0;
	m_描述集列表分配信息.descriptorPool = 参数池;
	m_描述集列表分配信息.descriptorSetCount = 1;
	m_描述集列表分配信息.pSetLayouts = &m_参数布局;

	VkDescriptorSet 描述集列表 = nullptr;
	res = vkAllocateDescriptorSets(设备, &m_描述集列表分配信息, &描述集列表);
	assert(res == VK_SUCCESS);

	return (S_结构对象指针)描述集列表;
}

void f_setGPU参数布局(S_板载缓存* 渲染参数, S_结构对象指针 GPU参数set) {
	VkDevice 设备 = (VkDevice)(渲染参数->m_Ctx.m_逻辑设备.设备);
	
	
	S_VkArray缓存* 缓存 = dynamic_cast<S_VkArray缓存*>(渲染参数);

	VkWriteDescriptorSet writes{};								
	writes.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;		//结构体类型
	writes.pNext = NULL;										//自定义数据的指针
	writes.descriptorCount = 1;									//描述数量
	writes.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;	//描述类型
	writes.pBufferInfo = &(缓存->m_Data.m_Buffer_info);			//对应一致变量缓冲的信息
	writes.dstArrayElement = 0;									//目标数组起始元素
	writes.dstBinding = 0;//目标绑定编号
	writes.dstSet = (VkDescriptorSet)GPU参数set;


	vkUpdateDescriptorSets(设备, 1, &writes, 0, NULL);
}

/*void f_setGPU参数布局_2D绘制(S_着色* shader, S_2D绘制GPU全局参数& view, S_板载缓存** 参数元素, uint16 num, S_纹理** 纹理参数, uint16 texNum) {
	S_Vk着色* s = dynamic_cast<S_Vk着色*>(shader);
	VkDevice 设备 = s->m_设备;

	S_VkArray缓存* 视图矩阵 = dynamic_cast<S_VkArray缓存*>((S_板载缓存*)(view.m_视图矩阵));


	std::vector<VkWriteDescriptorSet> writes(num + 1 + texNum);							//完善一致变量写入描述集实例数组


	writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;							//结构体类型
	writes[0].pNext = NULL;																//自定义数据的指针
	writes[0].descriptorCount = 1;														//描述数量
	writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;						//描述类型
	writes[0].pBufferInfo = &视图矩阵->m_Data.m_Buffer_info;							//对应一致变量缓冲的信息
	writes[0].dstArrayElement = 0;														//目标数组起始元素
	writes[0].dstBinding = 0;															//目标绑定编号
	writes[0].dstSet = (VkDescriptorSet)view.m_GPU参数;
	

	
	for (uint32 i = 1; i <= num; ++i) {
		auto buf = dynamic_cast<S_VkArray缓存*>(参数元素[i-1]);
		if (view.m_GPU参数 == nullptr) {
			cout << view.m_GPU参数;
		}
		writes[i].sType				= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;			//结构体类型
		writes[i].pNext				= NULL;												//自定义数据的指针
		writes[i].descriptorCount	= 1;												//描述数量
		writes[i].descriptorType	= (VkDescriptorType)f_get缓存布局类型(buf->m_Type);	//描述类型
		writes[i].pBufferInfo		= &(buf->m_Data.m_Buffer_info);						//对应一致变量缓冲的信息
		writes[i].dstArrayElement	= 0;												//目标数组起始元素
		writes[i].dstBinding		= i;												//目标绑定编号
		writes[i].dstSet			= (VkDescriptorSet)view.m_GPU参数;
		writes[i].pImageInfo = 0;

	}
	//VkBufferUsageFlagBits;
	int32 Binding = 10;
	for (uint32 i = 0; i < texNum; ++i) {
		uint16 id = num + 1 + i;
		if ((VkDescriptorSet)view.m_GPU参数 == nullptr) {
			cout << view.m_GPU参数;
		}
		writes[id].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;				//结构体类型
		writes[id].pNext = NULL;												//自定义数据的指针
		writes[id].descriptorCount = 1;											
		writes[id].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;	
		writes[id].pBufferInfo = 0;						
		writes[id].dstArrayElement = 0;											
		writes[id].dstBinding = Binding;												//目标绑定编号
		writes[id].dstSet				= (VkDescriptorSet)view.m_GPU参数;
		//writes[id].pImageInfo = &(((S_VkImage*)(纹理参数[i]))->m_着色器参数);
		writes[id].pImageInfo = &(((S_VkImage*)纹理参数[i])->m_着色器参数);

		if (!writes[id].pImageInfo) {
			std::cout << "纹理参数[i]" << std::endl;
		}

		++Binding;
	}
	
	vkUpdateDescriptorSets(设备, writes.size(), writes.data(), 0, NULL);
}*/


void f_setGPU参数布局_2D绘制(S_着色* shader, S_2D绘制GPU全局参数& view) {
	S_Vk着色* s = dynamic_cast<S_Vk着色*>(shader);
	//VkDevice 设备 = s->m_设备;

	S_VkArray缓存* 视图矩阵 = dynamic_cast<S_VkArray缓存*>((S_板载缓存*)(view.m_视图矩阵));
	S_2D笔刷& 笔刷 = *((S_2D笔刷*)(view.m_2D笔刷));


	std::vector<VkWriteDescriptorSet> writes(笔刷.m_参数元素数量 + 笔刷.m_纹理参数数量 + 1);	 //完善一致变量写入描述集实例数组
	//std::vector<VkWriteDescriptorSet> writes(笔刷.m_参数元素数量 + 笔刷.m_纹理参数数量);		 //完善一致变量写入描述集实例数组


	writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;							//结构体类型
	writes[0].pNext = NULL;																//自定义数据的指针
	writes[0].descriptorCount = 1;														//描述数量
	writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;						//描述类型
	writes[0].pBufferInfo = &(视图矩阵->m_Data.m_Buffer_info);							//对应一致变量缓冲的信息
	writes[0].dstArrayElement = 0;														//目标数组起始元素
	writes[0].dstBinding = 0;															//目标绑定编号
	writes[0].dstSet = (VkDescriptorSet)(笔刷.m_材质->m_GPU参数set);



	for (uint32 i = 0; i < 笔刷.m_参数元素数量; ++i) {
		auto buf = (S_VkArray缓存*)(笔刷.m_参数元素[i]);
		uint16 id = i + 1;
		//uint16 id = i;

		writes[id].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;						//结构体类型
		writes[id].pNext = NULL;															//自定义数据的指针
		writes[id].descriptorCount = 1;													//描述数量
		writes[id].descriptorType = (VkDescriptorType)f_get缓存布局类型(buf->m_Type);	//描述类型
		writes[id].pBufferInfo = &(buf->m_Data.m_Buffer_info);							//对应一致变量缓冲的信息
		writes[id].dstArrayElement = 0;													//目标数组起始元素
		writes[id].dstBinding = 笔刷.m_GPU绑定位置[i];									//目标绑定编号
		writes[id].dstSet = (VkDescriptorSet)(笔刷.m_材质->m_GPU参数set);
		writes[id].pImageInfo = 0;
	}

	int32 Binding = DEF_BINDING_WIDGET_Texture;
	for (uint32 i = 0; i < 笔刷.m_纹理参数数量; ++i) {
		uint16 id = 笔刷.m_参数元素数量 + i + 1;
		//uint16 id = 笔刷.m_参数元素数量 + i;

		if ((VkDescriptorSet)view.m_GPU参数 == nullptr) {
			cout << view.m_GPU参数;
		}
		writes[id].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;				//结构体类型
		writes[id].pNext = NULL;												//自定义数据的指针
		writes[id].descriptorCount = 1;
		writes[id].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
		writes[id].pBufferInfo = 0;
		writes[id].dstArrayElement = 0;
		writes[id].dstBinding = Binding;												//目标绑定编号
		writes[id].dstSet = (VkDescriptorSet)(笔刷.m_材质->m_GPU参数set);
		writes[id].pImageInfo = &(((S_VkImage*)笔刷.m_纹理参数[i])->m_着色器参数);

		if (!writes[id].pImageInfo) {
			std::cout << "纹理参数[i]" << std::endl;
		}

		++Binding;
	}

	vkUpdateDescriptorSets(s->m_设备, writes.size(), writes.data(), 0, NULL);
}







void f_setGPU参数布局(S_着色* shader, S_结构对象指针 dstSet, const S_GPU参数布局& GPU参数) {
	S_Vk着色* s = dynamic_cast<S_Vk着色*>(shader);
	VkDevice 设备 = s->m_设备;


	std::vector<VkWriteDescriptorSet> writes(GPU参数.m_参数数量 + GPU参数.m_纹理数量);							//完善一致变量写入描述集实例数组

	for (uint32 i = 0; i < GPU参数.m_参数数量; ++i) {
		auto buf = dynamic_cast<S_VkArray缓存*>(GPU参数.m_参数槽[i]);

		writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;						//结构体类型
		writes[i].pNext = NULL;															//自定义数据的指针
		writes[i].descriptorCount = 1;													//描述数量
		writes[i].descriptorType = (VkDescriptorType)f_get缓存布局类型(buf->m_Type);	//描述类型
		writes[i].pBufferInfo = &(buf->m_Data.m_Buffer_info);							//对应一致变量缓冲的信息
		writes[i].dstArrayElement = 0;													//目标数组起始元素
		writes[i].dstBinding = i;														//目标绑定编号
		writes[i].dstSet = (VkDescriptorSet)dstSet;
		writes[i].pImageInfo = 0;
	}

	int32 Binding = 10;
	for (uint32 i = 0; i < GPU参数.m_纹理数量; ++i) {
		uint16 id = GPU参数.m_参数数量 + i;

		writes[id].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;				//结构体类型
		writes[id].pNext = NULL;												//自定义数据的指针
		writes[id].descriptorCount = 1;
		writes[id].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
		writes[id].pBufferInfo = 0;
		writes[id].dstArrayElement = 0;
		writes[id].dstBinding = Binding;												//目标绑定编号
		writes[id].dstSet = (VkDescriptorSet)dstSet;
		
		writes[id].pImageInfo = &(((S_VkImage*)GPU参数.m_纹理槽[i])->m_着色器参数);

		++Binding;
	}

	vkUpdateDescriptorSets(设备, writes.size(), writes.data(), 0, NULL);
}

void f_setGPU参数布局(S_材质* 材质, const S_GPU参数布局& GPU参数) {
	S_Vk着色* s = dynamic_cast<S_Vk着色*>(材质->m_Shader);
	VkDevice 设备 = s->m_设备;


	std::vector<VkWriteDescriptorSet> writes(GPU参数.m_参数数量 + GPU参数.m_纹理数量);							//完善一致变量写入描述集实例数组

	for (uint32 i = 0; i < GPU参数.m_参数数量; ++i) {
		auto buf = dynamic_cast<S_VkArray缓存*>(GPU参数.m_参数槽[i]);

		writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;						//结构体类型
		writes[i].pNext = NULL;															//自定义数据的指针
		writes[i].descriptorCount = 1;													//描述数量
		writes[i].descriptorType = (VkDescriptorType)f_get缓存布局类型(buf->m_Type);	//描述类型
		writes[i].pBufferInfo = &(buf->m_Data.m_Buffer_info);							//对应一致变量缓冲的信息
		writes[i].dstArrayElement = 0;													//目标数组起始元素
		writes[i].dstBinding = GPU参数.m_绑定位置[i];														//目标绑定编号
		writes[i].dstSet = (VkDescriptorSet)材质->m_GPU参数set;
		writes[i].pImageInfo = 0;
	}

	int32 Binding = 10;
	for (uint32 i = 0; i < GPU参数.m_纹理数量; ++i) {
		uint16 id = GPU参数.m_参数数量 + i;

		writes[id].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;				//结构体类型
		writes[id].pNext = NULL;												//自定义数据的指针
		writes[id].descriptorCount = 1;
		writes[id].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
		writes[id].pBufferInfo = 0;
		writes[id].dstArrayElement = 0;
		writes[id].dstBinding = Binding;												//目标绑定编号
		writes[id].dstSet = (VkDescriptorSet)材质->m_GPU参数set;

		writes[id].pImageInfo = &(((S_VkImage*)GPU参数.m_纹理槽[i])->m_着色器参数);

		++Binding;
	}

	vkUpdateDescriptorSets(设备, writes.size(), writes.data(), 0, NULL);
}

void f_df_setGPU参数槽(S_结构对象指针 device, S_结构对象指针 GPU参数设置, const S_GPU参数槽& GPU参数) {
	if (!GPU参数.m_参数数量) return;

	VkDevice 设备 = (VkDevice)device;
	VkDescriptorSet DS = (VkDescriptorSet)GPU参数设置;
	
	std::vector<VkWriteDescriptorSet> writes(GPU参数.m_参数数量);
	for (uint32 i = 0; i < GPU参数.m_参数数量; ++i) {
		writes[i].pImageInfo = 0;
		writes[i].pNext = nullptr;

		switch (GPU参数.m_参数类型[i]) {
		case E_板载缓存类型::e_光追BVH: {
			VkWriteDescriptorSetAccelerationStructureKHR* info = (VkWriteDescriptorSetAccelerationStructureKHR*)malloc(sizeof(VkWriteDescriptorSetAccelerationStructureKHR));
			(*info) = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR };
			(*info).accelerationStructureCount = 1;
			(*info).pAccelerationStructures = &f_buf_get加速结构((S_VkArray缓存*)(GPU参数.m_参数槽[i]));
			writes[i].pNext = info;
			break;
		}
		case E_板载缓存类型::e_SAMPLER: 
		case E_板载缓存类型::e_IMAGE_SAMPLER: {
			writes[i].pImageInfo = (VkDescriptorImageInfo*)(GPU参数.m_参数槽[i]);
			break;
		}
		case E_板载缓存类型::e_IMAGE: {
			//auto tex = ((S_VkImage*)(GPU参数.m_参数槽[i]))->m_着色器参数;
			writes[i].pImageInfo = &(((S_VkImage*)(GPU参数.m_参数槽[i]))->m_着色器参数);
			break;
		}
		default: {
			auto buf = static_cast<S_VkArray缓存*>(GPU参数.m_参数槽[i]);
			writes[i].pBufferInfo = &buf->m_Data.m_Buffer_info;
			break;
		}
		}
		
		writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;						                       //结构体类型
		writes[i].descriptorCount = GPU参数.m_绑定数量[i];													   //描述数量
		writes[i].descriptorType = (VkDescriptorType)f_get缓存布局类型(E_板载缓存类型(GPU参数.m_参数类型[i])); 
		writes[i].dstArrayElement = 0;													//目标数组起始元素
		writes[i].dstBinding = GPU参数.m_绑定位置[i];									//目标绑定编号
		writes[i].dstSet = DS;
		
	}

	vkUpdateDescriptorSets(设备, writes.size(), writes.data(), 0, VK_NULL_HANDLE);

	for (auto& e : writes) {
		if(e.pNext) free(const_cast<void*>(e.pNext));
	}
}

void f_setGPU参数布局(S_GPU计算* GPU, const S_GPU参数布局& GPU参数) {
	S_Vk着色* s = dynamic_cast<S_Vk着色*>(GPU->m_Shader);

	std::vector<VkWriteDescriptorSet> writes(GPU参数.m_参数数量);						

	for (uint32 i = 0; i < GPU参数.m_参数数量; ++i) {
		auto buf = dynamic_cast<S_VkArray缓存*>(GPU参数.m_参数槽[i]);

		writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;						//结构体类型
		writes[i].pNext = NULL;															//自定义数据的指针
		writes[i].descriptorCount = 1;													//描述数量
		writes[i].descriptorType = (VkDescriptorType)f_get缓存布局类型(buf->m_Type);	//描述类型
		writes[i].pBufferInfo = &(buf->m_Data.m_Buffer_info);							//对应一致变量缓冲的信息
		writes[i].dstArrayElement = 0;													//目标数组起始元素
		writes[i].dstBinding = GPU参数.m_绑定位置[i];									//目标绑定编号
		writes[i].dstSet = (VkDescriptorSet)GPU->m_GPU参数set;
		writes[i].pImageInfo = 0;
	}

	vkUpdateDescriptorSets(s->m_设备, writes.size(), writes.data(), 0, NULL);
}

void f_df_upGPU参数(S_结构对象指针 device, S_结构对象指针 GPU参数设置, const S_GPU参数槽& GPU参数) {
	assert(GPU参数.m_参数数量);

	VkDevice 设备 = (VkDevice)device;
	VkDescriptorSet DS = (VkDescriptorSet)GPU参数设置;

	std::vector<VkWriteDescriptorSet> writes(GPU参数.m_参数数量);
	for (uint32 i = 0; i < GPU参数.m_参数数量; ++i) {
		writes[i] = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
		
		switch (GPU参数.m_参数类型[i]) {
			case E_板载缓存类型::e_光追BVH: {
				auto& 块 = *(S_GPU内存块索引*)(GPU参数.m_参数槽[i]);
				f_buf_get加速结构(块);
				writes[i].pNext = 块.m_Acc;
				break;
			}
			case E_板载缓存类型::e_SAMPLER:
			case E_板载缓存类型::e_IMAGE_SAMPLER: {
				writes[i].pImageInfo = (VkDescriptorImageInfo*)(GPU参数.m_参数槽[i]);
				break;
			}
			case E_板载缓存类型::e_IMAGE: {
				//auto tex = ((S_VkImage*)(GPU参数.m_参数槽[i]))->m_着色器参数;
				writes[i].pImageInfo = &(((S_VkImage*)(GPU参数.m_参数槽[i]))->m_着色器参数);
				break;
			}
			default: {
				auto& 块 = *(S_GPU内存块索引*)(GPU参数.m_参数槽[i]);
				auto& buf = *static_cast<S_VkArray缓存*>(块.m_Buf);
				writes[i].pBufferInfo = &buf.m_Data.m_Buffer_info;
				break;
			}
		}

		writes[i].descriptorCount = GPU参数.m_绑定数量[i];													   //描述数量
		writes[i].descriptorType  = (VkDescriptorType)f_get缓存布局类型(E_板载缓存类型(GPU参数.m_参数类型[i]));
		writes[i].dstArrayElement = 0;													//目标数组起始元素
		writes[i].dstBinding      = GPU参数.m_绑定位置[i];									//目标绑定编号
		writes[i].dstSet          = DS;
	}

	vkUpdateDescriptorSets(设备, writes.size(), writes.data(), 0, VK_NULL_HANDLE);

	//for (auto& e : writes) {
	//	if (e.pNext) free(const_cast<void*>(e.pNext));
	//}
}




void f_绑定Vertex(S_设备环境& ctx, S_板载缓存** buf, uint8 num) {
	//S_VkArray缓存** b = (S_VkArray缓存**)malloc(sizeof(S_VkArray缓存*) * num);
	S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_逻辑设备.pNext;

	VkBuffer* b = (VkBuffer*)calloc(num, sizeof(VkBuffer));
	VkDeviceSize* f = (VkDeviceSize*)calloc(num, sizeof(VkDeviceSize));
	uint64 offset = 0;
	for (uint8 i = 0; i < num; ++i) {
		b[i] = dynamic_cast<S_VkArray缓存*>(buf[i])->m_Data.m_Buf;
		//f[i] = dynamic_cast<S_VkArray缓存*>(buf[i])->m_Data.m_Buffer_info.offset;
		f[i] = offset;
		//vkCmdBindVertexBuffers(info->m_命令缓存, 0, 1, &dynamic_cast<S_VkArray缓存*>(buf[i])->m_Data.m_Buf, f);
		//offset = dynamic_cast<S_VkArray缓存*>(buf[i])->m_Data.m_Buffer_info.offset;
	}								//顶点数据偏移量数组
	vkCmdBindVertexBuffers(info->m_命令缓存, 0, 1, b, f);

	free(b);
	free(f);
}

void f_绑定Vertex(S_设备环境& ctx, S_板载缓存* buf) {
	//S_VkArray缓存** b = (S_VkArray缓存**)malloc(sizeof(S_VkArray缓存*) * num);
	S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_绘图设备配置;
	VkDeviceSize f[1] = { 0 };
	//顶点数据偏移量数组
	vkCmdBindVertexBuffers(info->m_命令缓存, 0, 1, &(dynamic_cast<S_VkArray缓存*>(buf)->m_Data.m_Buf), f);
}



void f_绑定Index(S_设备环境& ctx, S_板载缓存* buf) {
	S_VkArray缓存* b = dynamic_cast<S_VkArray缓存*>(buf);
	S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_绘图设备配置;
	//buf->m_Offset;
	vkCmdBindIndexBuffer(info->m_命令缓存, b->m_Data.m_Buf, 0, VK_INDEX_TYPE_UINT32);
}

void f_Ex绑定Index(S_设备环境& ctx, S_板载缓存* buf) {
	S_VkArray缓存* b = dynamic_cast<S_VkArray缓存*>(buf);
	S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_绘图设备配置;

	VkIndexType type;
	switch (buf->m_Offset) {
	case 2:
		type = VK_INDEX_TYPE_UINT16;
		break;
	case 4:
		type = VK_INDEX_TYPE_UINT32;
		break;
	}
	
	vkCmdBindIndexBuffer(info->m_命令缓存, b->m_Data.m_Buf, 0, type);
}



void f_Draw_序列(S_设备环境& ctx, S_材质* material, S_板载缓存* 顶点, S_渲染参数& 渲染参数) {
	S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_绘图设备配置;

	S_Vk线管* pipeline = dynamic_cast<S_Vk线管*>(material->m_Pipeline);
	S_Vk着色* shader = dynamic_cast<S_Vk着色*>(material->m_Shader);
	

	vkCmdSetViewport(info->m_命令缓存, 0, 1, (VkViewport*)渲染参数.m_视口);
	vkCmdSetScissor(info->m_命令缓存, 0, 1, (VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetLineWidth(info->m_命令缓存, 渲染参数.m_线宽);
	
	
	VkDescriptorSet s = (VkDescriptorSet)渲染参数.m_GPU参数;
	vkCmdBindPipeline(info->m_命令缓存, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->m_线管);//将当前使用的命令缓冲与指定管线绑定
	vkCmdBindDescriptorSets(info->m_命令缓存, VK_PIPELINE_BIND_POINT_GRAPHICS, shader->m_线管布局, 0, 
		1, &s, 0, NULL);//将命令缓冲、管线布局、描述集绑定


	if(顶点) f_绑定Vertex(ctx, 顶点);
	//vkCmdBindVertexBuffers(info->m_命令缓存, 0, 1, &b->m_Data.m_Buf, offsetsVertex);	
	vkCmdDraw(info->m_命令缓存, 渲染参数.m_顶点数量, 渲染参数.m_实例数量, 渲染参数.m_顶点内存偏移, 渲染参数.m_实例偏移);
	/*cout << "渲染参数.m_顶点数量" << 渲染参数.m_顶点数量 << endl;
	cout<<"渲染参数.m_实例数量"<<渲染参数.m_实例数量<<endl;
	cout<<"渲染参数.m_顶点内存偏移"<<渲染参数.m_顶点内存偏移<<endl;
	cout<<"渲染参数.m_实例偏移"<<渲染参数.m_实例偏移<<endl;
	if (渲染参数.m_顶点数量 > 30000) {
		渲染参数.m_顶点数量;
		cout<<"渲染参数.m_顶点数量"<<渲染参数.m_顶点数量<<endl;
	}*/
}

void f_Draw_间接序列(S_设备环境& ctx, S_材质* material, S_板载缓存* 顶点, S_渲染参数& 渲染参数) {
	S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_绘图设备配置;

	S_Vk线管* pipeline = dynamic_cast<S_Vk线管*>(material->m_Pipeline);
	S_Vk着色* shader = dynamic_cast<S_Vk着色*>(material->m_Shader);
	
	

	vkCmdSetViewport(info->m_命令缓存, 0, 1, (VkViewport*)渲染参数.m_视口);
	vkCmdSetScissor(info->m_命令缓存, 0, 1, (VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetLineWidth(info->m_命令缓存, 渲染参数.m_线宽);

	VkDescriptorSet s = (VkDescriptorSet)(渲染参数.m_GPU参数);
	vkCmdBindPipeline(info->m_命令缓存, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->m_线管);
	vkCmdBindDescriptorSets(info->m_命令缓存, VK_PIPELINE_BIND_POINT_GRAPHICS, shader->m_线管布局, 0, 1, &s, 0, NULL);//将命令缓冲、管线布局、描述集绑定
	

	f_绑定Vertex(ctx, 顶点);	
	//vkCmdDrawIndirect(info->m_命令缓存, ((S_VkArray缓存*)渲染参数.m_间接绘制)->m_Data.m_Buf, 0, ((S_VkArray缓存*)渲染参数.m_间接绘制)->m_Size, sizeof(VkDrawIndirectCommand));
	vkCmdDrawIndirect(info->m_命令缓存, ((S_VkArray缓存*)渲染参数.m_间接->m_Buf)->m_Data.m_Buf, 渲染参数.m_间接->m_Mem.m_偏移*sizeof(VkDrawIndirectCommand), 渲染参数.m_间接->m_Mem.m_大小, sizeof(VkDrawIndirectCommand));
	//vkCmdDrawIndirect(info->m_命令缓存, ((S_VkArray缓存*)渲染参数.m_间接->m_Buf)->m_Data.m_Buf, 渲染参数.m_间接->m_Mem.m_偏移, 渲染参数.m_间接->m_Mem.m_大小, sizeof(VkDrawIndirectCommand));
	//cout << "渲染参数.m_间接->m_Mem.m_大小 = " << 渲染参数.m_间接->m_Mem.m_大小 << endl;
	//auto a = f_buf_Indirect_ptr(*渲染参数.m_间接);
	//for (uint32 i = 0; i < 渲染参数.m_间接->m_Mem.m_大小; ++i) {
	//	//auto m = ((Mat44f*)顶点->m_mappedPtr)[a[i].firstInstance];
	//	if (a[i].firstInstance > 100000 || a[i].firstVertex > 100000 | a[i].instanceCount > 100000 || a[i].vertexCount > 100000) {
	//		cout<<"渲染参数.m_间接->m_Mem.m_大小 = "<< a[i].firstInstance << endl;
	//	}
	//}
}

void f_Draw_索引三角形(S_设备环境& ctx, S_材质* material, S_板载缓存* vert, S_索引渲染参数& 索引渲染参数, S_渲染参数& 渲染参数) {
	S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_逻辑设备.pNext;

	S_Vk线管* pipeline = dynamic_cast<S_Vk线管*>(material->m_Pipeline);
	S_Vk着色* shader = dynamic_cast<S_Vk着色*>(material->m_Shader);


	vkCmdSetViewport(info->m_命令缓存, 0, 1, (VkViewport*)渲染参数.m_视口);
	vkCmdSetScissor(info->m_命令缓存, 0, 1, (VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetLineWidth(info->m_命令缓存, 渲染参数.m_线宽);
	
	VkDescriptorSet s = (VkDescriptorSet)渲染参数.m_GPU参数;
	vkCmdBindPipeline(info->m_命令缓存, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->m_线管);//将当前使用的命令缓冲与指定管线绑定
	vkCmdBindDescriptorSets(info->m_命令缓存, VK_PIPELINE_BIND_POINT_GRAPHICS, shader->m_线管布局, 0,
		1, &s, 0, NULL);//将命令缓冲、管线布局、描述集绑定


	f_绑定Vertex(ctx, vert);
	f_绑定Index(ctx, (S_板载缓存*)索引渲染参数.m_索引);
	if (渲染参数.m_间接绘制) {
		vkCmdDrawIndexedIndirect(info->m_命令缓存, ((S_VkArray缓存*)渲染参数.m_间接绘制)->m_Data.m_Buf, 0, ((S_VkArray缓存*)渲染参数.m_间接绘制)->m_Size, sizeof(VkDrawIndexedIndirectCommand));
	}
	else {
		vkCmdDrawIndexed(info->m_命令缓存, 渲染参数.m_索引内存数量, 渲染参数.m_实例数量, 渲染参数.m_索引内存偏移, 渲染参数.m_顶点内存偏移, 渲染参数.m_实例偏移);
	}
	
}

void f_Draw2D_索引三角形(S_设备环境& ctx, S_材质* material, S_板载缓存* vert, S_索引渲染参数& 索引渲染参数, S_渲染参数& 渲染参数) {
	//S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_逻辑设备.pNext;
	S_绘图设备配置* info = (S_绘图设备配置*)ctx.m_绘图设备配置;

	S_Vk线管* pipeline = dynamic_cast<S_Vk线管*>(material->m_Pipeline);
	S_Vk着色* shader = dynamic_cast<S_Vk着色*>(material->m_Shader);
	

	VkRect2D v = *((VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetViewport(info->m_命令缓存, 0, 1, (VkViewport*)渲染参数.m_视口);
	vkCmdSetScissor(info->m_命令缓存, 0, 1, (VkRect2D*)渲染参数.m_裁剪);
	vkCmdSetLineWidth(info->m_命令缓存, 渲染参数.m_线宽);
	

	VkDescriptorSet s = (VkDescriptorSet)渲染参数.m_GPU参数;
	vkCmdBindPipeline(info->m_命令缓存, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->m_线管);//将当前使用的命令缓冲与指定管线绑定
	vkCmdBindDescriptorSets(info->m_命令缓存, VK_PIPELINE_BIND_POINT_GRAPHICS, shader->m_线管布局, 0, 1, &s, 0, NULL);


	f_绑定Vertex(ctx, vert);
	f_Ex绑定Index(ctx, (S_板载缓存*)索引渲染参数.m_索引);
	vkCmdDrawIndexed(info->m_命令缓存, 渲染参数.m_索引内存数量, 渲染参数.m_实例数量, 渲染参数.m_索引内存偏移, 渲染参数.m_顶点内存偏移, 0);
}





void f_GPU_run计算(S_GPU计算* gpu, uvec3 dim, void* data, uint32 size, uint8 列队) {
	VkDevice 设备			= (VkDevice)gpu->m_Ctx.m_逻辑设备.设备;
	S_绘图设备配置* info	= (S_绘图设备配置*)f_df_get绘图环境(gpu->m_Ctx);

	S_Vk计算线管* pipeline	= dynamic_cast<S_Vk计算线管*>(gpu->m_Pipeline);
	S_Vk着色* shader		= dynamic_cast<S_Vk着色*>(gpu->m_Shader);

	VkResult result;

	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;


	result = vkResetCommandBuffer(info->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(info->m_命令缓存, &cmd_buf_info);
	assert(result == VK_SUCCESS);


	
	vector<uint32_t> l(1);
	VkDescriptorSet s = (VkDescriptorSet)gpu->m_GPU参数set;
	vkCmdBindPipeline(info->m_命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->m_线管);
	vkCmdBindDescriptorSets(info->m_命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, shader->m_线管布局, 0, 1, &s, 0, l.data());
	
	if (data) {
		vkCmdPushConstants(info->m_命令缓存, shader->m_线管布局, VK_SHADER_STAGE_COMPUTE_BIT, 0, size, data);
	}

	vkCmdDispatch(info->m_命令缓存, dim.x, dim.y, dim.z);
	
	result = vkEndCommandBuffer(info->m_命令缓存);
	assert(result == VK_SUCCESS);



	VkFenceCreateInfo fenceCreateInfo{};
	fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	fenceCreateInfo.flags = 0;
	VkFence fence;
	vkCreateFence(info->m_设备, &fenceCreateInfo, nullptr, &fence);

	VkSubmitInfo 命令提交信息{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
	命令提交信息.commandBufferCount = 1;
	命令提交信息.pCommandBuffers = (VkCommandBuffer*)&(info->m_命令缓存);
	result = vkQueueSubmit(info->m_图形列队[列队 ? 列队 : info->m_列队ID], 1, &命令提交信息, fence);
	//result = vkQueueWaitIdle(info->m_图形列队[info->m_列队ID]);
	do {
		result = vkWaitForFences(info->m_设备, 1, &fence, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	vkDestroyFence(info->m_设备, fence, nullptr);
}





void f_GPU_run计算(S_GPU计算* gpu, S_结构对象指针 命令缓存, uvec3 dim, void* data, uint32 size, uint8 列队) {
	VkDevice 设备 = (VkDevice)gpu->m_Ctx.m_逻辑设备.设备;
	S_绘图设备配置* info = (S_绘图设备配置*)f_df_get绘图环境(gpu->m_Ctx);

	S_Vk计算线管* pipeline = dynamic_cast<S_Vk计算线管*>(gpu->m_Pipeline);
	S_Vk着色* shader = dynamic_cast<S_Vk着色*>(gpu->m_Shader);

	VkResult result;

	VkCommandBufferBeginInfo cmd_buf_info = {};
	cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	cmd_buf_info.pNext = NULL;
	cmd_buf_info.flags = 0;
	cmd_buf_info.pInheritanceInfo = NULL;


	result = vkResetCommandBuffer((VkCommandBuffer)命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer((VkCommandBuffer)命令缓存, &cmd_buf_info);
	assert(result == VK_SUCCESS);



	vector<uint32_t> l(1);
	VkDescriptorSet s = (VkDescriptorSet)gpu->m_GPU参数set;
	vkCmdBindPipeline((VkCommandBuffer)命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->m_线管);
	vkCmdBindDescriptorSets((VkCommandBuffer)命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, shader->m_线管布局, 0, 1, &s, 0, l.data());

	if (data) {
		vkCmdPushConstants((VkCommandBuffer)命令缓存, shader->m_线管布局, VK_SHADER_STAGE_COMPUTE_BIT, 0, size, data);
	}

	vkCmdDispatch((VkCommandBuffer)命令缓存, dim.x, dim.y, dim.z);

	result = vkEndCommandBuffer((VkCommandBuffer)命令缓存);
	assert(result == VK_SUCCESS);



	VkFenceCreateInfo fenceCreateInfo{};
	fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	fenceCreateInfo.flags = 0;
	VkFence fence;
	vkCreateFence(info->m_设备, &fenceCreateInfo, nullptr, &fence);

	VkSubmitInfo 命令提交信息{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
	命令提交信息.commandBufferCount = 1;
	命令提交信息.pCommandBuffers = (VkCommandBuffer*)&(info->m_命令缓存);
	result = vkQueueSubmit(info->m_图形列队[列队], 1, &命令提交信息, fence);
	//result = vkQueueWaitIdle(info->m_图形列队[info->m_列队ID]);
	do {
		result = vkWaitForFences(info->m_设备, 1, &fence, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	vkDestroyFence(info->m_设备, fence, nullptr);
}




void f_RayDraw_索引三角形(S_设备环境& ctx, S_材质* material, S_索引渲染参数& 索引渲染参数, S_渲染参数& 渲染参数) {
	S_绘图设备配置* info	= (S_绘图设备配置*)ctx.m_逻辑设备.pNext;
	S_Vk线管* pipeline		= dynamic_cast<S_Vk线管*>(material->m_Pipeline);
	S_Vk着色* shader		= dynamic_cast<S_Vk着色*>(material->m_Shader);

	VkDescriptorSet s = (VkDescriptorSet)渲染参数.m_GPU参数;

	vkCmdBindPipeline(info->m_命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->m_线管);
	vkCmdBindDescriptorSets(info->m_命令缓存, VK_PIPELINE_BIND_POINT_COMPUTE, shader->m_线管布局, 0, 1, &s, 0, 0);

	//vkCmdTraceRaysKHR(info->m_命令缓存, );

}











/*S_渲染环境* f_创建渲染环境(S_设备环境& ctx, E_MS次数 采样) {
	S_渲染环境* drawCtx = (S_渲染环境*)malloc(sizeof(S_渲染环境));
	//S_物理设备属性* prop = (S_物理设备属性*)ctx.m_物理设备.pNext;
	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);
	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)(ctx.m_逻辑设备.pNext);
	drawCtx->m_GPU属性 = ctx.m_物理设备.pNext;

	return drawCtx;
}*/

S_帧缓存* f_创建帧缓存(S_设备环境& ctx, const uvec2& faceSize, S_纹理** colors, uint32 num) {
	//VkDevice 逻辑设备 = ((S_绘图配置*)ctx.m_渲染设备)->m_设备;
	//S_物理设备属性* prop = ((S_绘图配置*)ctx.m_渲染设备)->m_硬件属性;
	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);
	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)(ctx.m_逻辑设备.pNext);


	//S_绘图配置& 绘图配置 = *((S_绘图配置*)绘图配置);
	S_Vk帧缓存* frameBuf = new S_Vk帧缓存(f_vec(faceSize));
	uvec3 area = { faceSize.x, faceSize.y, 1 };

	auto* 颜色图像 = f_tex_创建帧缓存纹理(ctx, area, colors[0]->m_格式, E_纹理维度类型::e_2D, ctx.m_采样数);
	frameBuf->m_交换面颜色缓存.push_back((S_VkImage*)(颜色图像));

	for (uint32 i = 0; i < num; ++i) {
		frameBuf->m_交换面颜色缓存.push_back((S_VkImage*)(colors[i]));
	}

	//S_纹理* depth[]
	for (uint32 i = 1; i < num; ++i) {
		auto* 深度图像 = f_tex_创建深度纹理(ctx, area, ctx.m_采样数, E_纹理格式::e_tf_D32F);
		frameBuf->m_交换面深度缓存.push_back((S_VkImage*)深度图像);
	}
	//这里采样必须是1
	auto* 深度图像 = f_tex_创建深度纹理(ctx, area, E_MS次数::e_MS_1, E_纹理格式::e_tf_D32F);
	frameBuf->m_交换面深度缓存.push_back((S_VkImage*)深度图像);

	
	//frameBuf->m_渲染通道 = f_创建渲染通道(逻辑设备, f_转VK图像格式(颜色图像->m_格式), f_转VK图像格式(深度图像->m_格式), 采样);
	frameBuf->f_构建交换链缓存(逻辑设备, 绘图设备配置->m_渲染通道, num*2);
	return frameBuf;
}

void f_构建帧多重采样缓存(S_设备环境& ctx, S_帧缓存* frame, const uvec2& faceSize, S_纹理** colors, uint32 num) {
	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);
	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)(ctx.m_逻辑设备.pNext);

	uvec3 area = { faceSize.x, faceSize.y, 1 };
	S_Vk帧缓存* frameBuf = dynamic_cast<S_Vk帧缓存*>(frame);

	auto* 颜色图像 = f_tex_创建帧缓存纹理(ctx, area, colors[0]->m_格式, E_纹理维度类型::e_2D, ctx.m_采样数);
	frameBuf->m_交换面颜色缓存.push_back((S_VkImage*)(颜色图像));

	for (uint32 i = 0; i < num; ++i) {
		frameBuf->m_交换面颜色缓存.push_back((S_VkImage*)(colors[i]));
	}

	//S_纹理* depth[]
	for (uint32 i = 1; i < num; ++i) {
		auto* 深度图像 = f_tex_创建深度纹理(ctx, area, ctx.m_采样数, E_纹理格式::e_tf_D32F);
		frameBuf->m_交换面深度缓存.push_back((S_VkImage*)深度图像);
	}
	//这里采样必须是1
	auto* 深度图像 = f_tex_创建深度纹理(ctx, area, E_MS次数::e_MS_1, E_纹理格式::e_tf_D32F);
	frameBuf->m_交换面深度缓存.push_back((S_VkImage*)深度图像);


	frameBuf->m_Size = f_vec(faceSize);
	//frameBuf->m_渲染通道 = f_创建渲染通道(逻辑设备, f_转VK图像格式(颜色图像->m_格式), f_转VK图像格式(深度图像->m_格式), 采样);
	frameBuf->f_构建交换链缓存(逻辑设备, 绘图设备配置->m_渲染通道, num * 2);
}


S_设备环境* f_创建渲染环境(S_设备环境& ctx, E_纹理格式 cf, E_纹理格式 df, E_MS次数 采样, const vec4& 清屏信息, uint16 线程数) {
	S_设备环境* drawCtx = (S_设备环境*)malloc(sizeof(S_设备环境));
	(*drawCtx) = ctx;
	drawCtx->m_采样数 = 采样;
	//drawCtx->m_物理设备 = ctx.m_物理设备;

	VkDevice 逻辑设备				= (VkDevice)(ctx.m_逻辑设备.设备);
	S_绘图设备配置* 绘图设备配置	= (S_绘图设备配置*)(ctx.m_逻辑设备.pNext);
	


	S_绘图设备配置* 绘图配置 = (S_绘图设备配置*)malloc(sizeof(S_绘图设备配置));
	drawCtx->m_逻辑设备.pNext = (S_结构对象指针)绘图配置;
	drawCtx->m_绘图设备配置 = 绘图配置;

	(*绘图配置) = (*绘图设备配置);
	绘图配置->m_列队ID = 1;
	
	绘图配置->m_渲染通道 = f_创建纹理渲染通道(逻辑设备, f_转VK图像格式(cf), f_转VK图像格式(df), 采样);
	//绘图配置->m_渲染通道 = f_创建渲染通道(逻辑设备, f_转VK图像格式(cf), f_转VK图像格式(df), 采样);
	绘图配置->m_命令缓存数 = 线程数;




	VkResult result;

	绘图配置->m_命令开始信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	绘图配置->m_命令开始信息.pNext = NULL; //自定义数据指针
	绘图配置->m_命令开始信息.flags = 0;
	绘图配置->m_命令开始信息.pInheritanceInfo = 0;
	


	//二级命令缓冲的继承信息
	绘图配置->m_二级命令缓存继承信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;		//结构体类型
	绘图配置->m_二级命令缓存继承信息.pNext = NULL;
	绘图配置->m_二级命令缓存继承信息.renderPass = 绘图配置->m_渲染通道;	//绑定对应的渲染通道
	绘图配置->m_二级命令缓存继承信息.subpass = 0;													//设置渲染子通道数量
	绘图配置->m_二级命令缓存继承信息.occlusionQueryEnable = VK_FALSE;								//关闭遮挡查询
	绘图配置->m_二级命令缓存继承信息.queryFlags = 0;												//设置查询标志
	绘图配置->m_二级命令缓存继承信息.pipelineStatistics = 0;										//控制统计如何执行的附加标志


	绘图配置->m_二级渲染开始信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	绘图配置->m_二级渲染开始信息.pNext = NULL; //自定义数据指针
	绘图配置->m_二级渲染开始信息.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
	绘图配置->m_二级渲染开始信息.pInheritanceInfo = &(绘图配置->m_二级命令缓存继承信息);			//命令缓冲继承信息



	/************************************************************************************/
	//                        命令缓存创建  主命令和子命令缓存
	/************************************************************************************/
	VkCommandPoolCreateInfo cmd_pool_info = {};														//构建命令池创建信息结构体实例
	cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	cmd_pool_info.pNext = NULL;																		//自定义数据的指针
	cmd_pool_info.queueFamilyIndex = 绘图设备配置->绘图列队家族Offset;								//绑定队列家族索引
	cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

	result = vkCreateCommandPool(逻辑设备, &cmd_pool_info, NULL, &(绘图配置->m_命令缓存池));
	assert(result == VK_SUCCESS);																	//检查命令池是否创建成功

	result = vkCreateCommandPool(逻辑设备, &cmd_pool_info, NULL, &(绘图配置->m_二级命令管道));
	assert(result == VK_SUCCESS);																	//检查命令池是否创建成功



	VkCommandBufferAllocateInfo cmdalloc = {}; 
	cmdalloc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmdalloc.pNext = NULL; 
	
	cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;									//分配的命令缓冲级别
	cmdalloc.commandPool = 绘图配置->m_命令缓存池;										//绑定命令池
	cmdalloc.commandBufferCount = 1;													//分配的命令缓冲数量
	result = vkAllocateCommandBuffers(逻辑设备, &cmdalloc, &(绘图配置->m_命令缓存));
	assert(result == VK_SUCCESS);

	cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;									//分配的命令缓冲级别
	cmdalloc.commandPool = 绘图配置->m_二级命令管道;									//绑定命令池
	cmdalloc.commandBufferCount = 线程数;												//分配的命令缓冲数量
	result = vkAllocateCommandBuffers(逻辑设备, &cmdalloc, 绘图配置->m_二级命令缓存);
	assert(result == VK_SUCCESS);






	VkSemaphoreCreateInfo 图像信号创建信息;
	图像信号创建信息.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
	图像信号创建信息.pNext = 0;
	图像信号创建信息.flags = 0;
	result = vkCreateSemaphore(逻辑设备, &图像信号创建信息, NULL, &绘图配置->m_图像获取信号量);
	assert(result == VK_SUCCESS);






	VkFenceCreateInfo fenceInfo;
	fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	fenceInfo.pNext = NULL;
	fenceInfo.flags = 0;
	vkCreateFence(逻辑设备, &fenceInfo, NULL, &(绘图配置->m_同步围栏));






	static VkClearValue ClearValue[3];
	ClearValue[0].color.float32[0] = 0.1f;
	ClearValue[0].color.float32[1] = 0.1f;
	ClearValue[0].color.float32[2] = 0.1f;
	ClearValue[0].color.float32[3] = 0.1f;

	ClearValue[1].color.float32[0] = 1.1f;
	ClearValue[1].color.float32[1] = 0.1f;
	ClearValue[1].color.float32[2] = 0.1f;
	ClearValue[1].color.float32[3] = 0.1f;

	ClearValue[2].depthStencil.depth = 1.0;
	ClearValue[2].depthStencil.stencil = 0;


	绘图配置->m_开始渲染信息 = {};
	绘图配置->m_开始渲染信息.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
	绘图配置->m_开始渲染信息.pNext = NULL;
	绘图配置->m_开始渲染信息.renderPass = 绘图配置->m_渲染通道;
	绘图配置->m_开始渲染信息.renderArea.offset.x = 0;
	绘图配置->m_开始渲染信息.renderArea.offset.y = 0;
	绘图配置->m_开始渲染信息.renderArea.extent.width = 1024;
	绘图配置->m_开始渲染信息.renderArea.extent.height = 576;
	绘图配置->m_开始渲染信息.clearValueCount = 3;
	绘图配置->m_开始渲染信息.pClearValues = ClearValue;

	
	

	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	绘图配置->m_命令提交信息 = {};
	绘图配置->m_命令提交信息.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	绘图配置->m_命令提交信息.pWaitDstStageMask = waitStages;

	//创建缓存需要设置信号量
	//绘图配置->m_命令提交信息.waitSemaphoreCount = 1;
	//绘图配置->m_命令提交信息.pWaitSemaphores = &绘图配置->m_图像获取信号量;
	绘图配置->m_命令提交信息.waitSemaphoreCount = 0;
	绘图配置->m_命令提交信息.pWaitSemaphores = 0;

	//绘图配置->m_命令提交信息.pCommandBuffers = 绘图配置->m_二级命令缓存;
	绘图配置->m_命令提交信息.commandBufferCount = 1;
	绘图配置->m_命令提交信息.pCommandBuffers = &绘图配置->m_命令缓存;

	绘图配置->m_命令提交信息.signalSemaphoreCount = 0;
	绘图配置->m_命令提交信息.pSignalSemaphores = 0;


	return drawCtx;
}

S_设备环境* f_创建计算环境(S_设备环境& ctx, uint16 线程数) {
	S_设备环境* compCtx = (S_设备环境*)malloc(sizeof(S_设备环境));
	(*compCtx) = ctx;

	VkDevice 逻辑设备 = (VkDevice)(ctx.m_逻辑设备.设备);
	S_绘图设备配置* old绘图设备配置 = (S_绘图设备配置*)(ctx.m_逻辑设备.pNext);



	S_绘图设备配置* 计算配置 = (S_绘图设备配置*)malloc(sizeof(S_绘图设备配置));
	compCtx->m_逻辑设备.pNext = (S_结构对象指针)计算配置;

	(*计算配置) = (*old绘图设备配置);
	计算配置->m_列队ID = 2;
	计算配置->m_命令缓存数 = 线程数;




	VkResult result;

	计算配置->m_命令开始信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	计算配置->m_命令开始信息.pNext = NULL; //自定义数据指针
	计算配置->m_命令开始信息.flags = 0;
	计算配置->m_命令开始信息.pInheritanceInfo = 0;



	//二级命令缓冲的继承信息
	计算配置->m_二级命令缓存继承信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;		//结构体类型
	计算配置->m_二级命令缓存继承信息.pNext = NULL;
	计算配置->m_二级命令缓存继承信息.renderPass = 计算配置->m_渲染通道;	//绑定对应的渲染通道
	计算配置->m_二级命令缓存继承信息.subpass = 0;													//设置渲染子通道数量
	计算配置->m_二级命令缓存继承信息.occlusionQueryEnable = VK_FALSE;								//关闭遮挡查询
	计算配置->m_二级命令缓存继承信息.queryFlags = 0;												//设置查询标志
	计算配置->m_二级命令缓存继承信息.pipelineStatistics = 0;										//控制统计如何执行的附加标志


	计算配置->m_二级渲染开始信息.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	计算配置->m_二级渲染开始信息.pNext = NULL; //自定义数据指针
	计算配置->m_二级渲染开始信息.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
	计算配置->m_二级渲染开始信息.pInheritanceInfo = &(计算配置->m_二级命令缓存继承信息);			//命令缓冲继承信息



	/************************************************************************************/
	//                        命令缓存创建  主命令和子命令缓存
	/************************************************************************************/

	VkCommandPoolCreateInfo cmd_pool_info = {}; //构建命令池创建信息结构体实例
	cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
	cmd_pool_info.pNext = NULL; //自定义数据的指针
	cmd_pool_info.queueFamilyIndex = old绘图设备配置->绘图列队家族Offset;//绑定队列家族索引
	cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;

	result = vkCreateCommandPool(逻辑设备, &cmd_pool_info, NULL, &(计算配置->m_命令缓存池));
	assert(result == VK_SUCCESS); //检查命令池是否创建成功

	result = vkCreateCommandPool(逻辑设备, &cmd_pool_info, NULL, &(计算配置->m_二级命令管道));
	assert(result == VK_SUCCESS); //检查命令池是否创建成功



	VkCommandBufferAllocateInfo cmdalloc = {};
	cmdalloc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
	cmdalloc.pNext = NULL;

	cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;									//分配的命令缓冲级别
	cmdalloc.commandPool = 计算配置->m_命令缓存池;										//绑定命令池
	cmdalloc.commandBufferCount = 1;													//分配的命令缓冲数量
	result = vkAllocateCommandBuffers(逻辑设备, &cmdalloc, &(计算配置->m_命令缓存));
	assert(result == VK_SUCCESS);

	cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;									//分配的命令缓冲级别
	cmdalloc.commandPool = 计算配置->m_二级命令管道;									//绑定命令池
	cmdalloc.commandBufferCount = 线程数;												//分配的命令缓冲数量
	result = vkAllocateCommandBuffers(逻辑设备, &cmdalloc, 计算配置->m_二级命令缓存);
	assert(result == VK_SUCCESS);




	VkSemaphoreCreateInfo 图像信号创建信息;
	图像信号创建信息.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
	图像信号创建信息.pNext = 0;
	图像信号创建信息.flags = 0;
	result = vkCreateSemaphore(逻辑设备, &图像信号创建信息, NULL, &计算配置->m_图像获取信号量);
	assert(result == VK_SUCCESS);




	VkFenceCreateInfo fenceInfo;
	fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
	fenceInfo.pNext = NULL;
	fenceInfo.flags = 0;
	vkCreateFence(逻辑设备, &fenceInfo, NULL, &(计算配置->m_同步围栏));





	VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT };
	计算配置->m_命令提交信息 = {};
	计算配置->m_命令提交信息.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
	计算配置->m_命令提交信息.pWaitDstStageMask = waitStages;

	//创建缓存需要设置信号量
	//绘图配置->m_命令提交信息.waitSemaphoreCount = 1;
	//绘图配置->m_命令提交信息.pWaitSemaphores = &绘图配置->m_图像获取信号量;
	计算配置->m_命令提交信息.waitSemaphoreCount = 0;
	计算配置->m_命令提交信息.pWaitSemaphores = 0;

	//绘图配置->m_命令提交信息.pCommandBuffers = 绘图配置->m_二级命令缓存;
	计算配置->m_命令提交信息.commandBufferCount = 1;
	计算配置->m_命令提交信息.pCommandBuffers = &计算配置->m_命令缓存;

	计算配置->m_命令提交信息.signalSemaphoreCount = 0;
	计算配置->m_命令提交信息.pSignalSemaphores = 0;




	return compCtx;
}

void f_修改帧缓存大小(S_帧缓存* frame, uvec2 size) {

}








void f_Draw_Begin_帧缓存(S_设备环境* 绘图配置, S_帧缓存* frame, uint8 id) {
	VkResult result;
	//S_绘图设备配置* 配置 = ((S_绘图设备配置*)绘图配置->m_逻辑设备.pNext);
	S_绘图设备配置* 配置 = ((S_绘图设备配置*)绘图配置->m_绘图设备配置);


	result = vkResetCommandBuffer(配置->m_命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer(配置->m_命令缓存, &配置->m_命令开始信息);
	assert(result == VK_SUCCESS);

	S_Vk帧缓存* 帧 = static_cast<S_Vk帧缓存*>(frame);
	配置->m_开始渲染信息.framebuffer = 帧->m_帧缓存[id];
	配置->m_开始渲染信息.renderPass;

	配置->m_开始渲染信息.renderArea.extent.width = frame->m_Size.x;
	配置->m_开始渲染信息.renderArea.extent.height = frame->m_Size.y;
	
	vkCmdBeginRenderPass(配置->m_命令缓存, &配置->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);
}

void f_Draw_end_帧缓存(S_设备环境* 绘图配置) {
	S_绘图设备配置* 配置 = ((S_绘图设备配置*)绘图配置->m_绘图设备配置);

	vkCmdEndRenderPass(配置->m_命令缓存);

	auto result = vkEndCommandBuffer(配置->m_命令缓存);
	assert(result == VK_SUCCESS);
	
	配置->m_命令提交信息.pCommandBuffers = &配置->m_命令缓存;
	result = vkQueueSubmit(配置->m_图形列队[配置->m_列队ID], 1, &(配置->m_命令提交信息), 配置->m_同步围栏);
	assert(result == VK_SUCCESS);
	
	do {
		result = vkWaitForFences(配置->m_设备, 1, &配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	vkResetFences(配置->m_设备, 1, &配置->m_同步围栏);
}





//void f_Draw_Begin_帧缓存(S_设备环境* 绘图配置, S_帧缓存* frame, S_结构对象指针 命令缓存, uint8 id) {
//	VkResult result;
//	//S_绘图设备配置* 配置 = ((S_绘图设备配置*)绘图配置->m_逻辑设备.pNext);
//	S_绘图设备配置* 配置 = ((S_绘图设备配置*)绘图配置->m_绘图设备配置);
//	VkCommandBuffer vk命令缓存 = (VkCommandBuffer)命令缓存;
//
//	result = vkResetCommandBuffer(vk命令缓存, 0);
//	assert(result == VK_SUCCESS);
//	result = vkBeginCommandBuffer(vk命令缓存, &配置->m_命令开始信息);
//	assert(result == VK_SUCCESS);
//
//	S_Vk帧缓存* 帧 = static_cast<S_Vk帧缓存*>(frame);
//	配置->m_开始渲染信息.framebuffer = 帧->m_帧缓存[id];
//	配置->m_开始渲染信息.renderPass;
//
//	配置->m_开始渲染信息.renderArea.extent.width = frame->m_Size.x;
//	配置->m_开始渲染信息.renderArea.extent.height = frame->m_Size.y;
//
//	vkCmdBeginRenderPass(vk命令缓存, &配置->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);
//}
//
//
//void f_Draw_end_帧缓存(S_设备环境* 绘图配置, S_结构对象指针 命令缓存, S_结构对象指针 fenc) {
//	S_绘图设备配置* 配置 = ((S_绘图设备配置*)绘图配置->m_绘图设备配置);
//
//	VkCommandBuffer vk命令缓存 = (VkCommandBuffer)命令缓存;
//	VkFence 同步 = 配置->m_同步围栏;
//	if (fenc) {
//		同步 = (VkFence)fenc;
//	}
//
//	vkCmdEndRenderPass(vk命令缓存);
//
//	auto result = vkEndCommandBuffer(vk命令缓存);
//	assert(result == VK_SUCCESS);
//
//	配置->m_命令提交信息.pCommandBuffers = &vk命令缓存;
//	result = vkQueueSubmit(配置->m_图形列队[配置->m_列队ID], 1, &(配置->m_命令提交信息), 同步);
//	assert(result == VK_SUCCESS);
//
//	do {
//		result = vkWaitForFences(配置->m_设备, 1, &同步, VK_TRUE, FENCE_TIMEOUT);
//	} while (result == VK_TIMEOUT);
//	vkResetFences(配置->m_设备, 1, &同步);
//}







void f_Draw_Begin(S_设备环境* ctx, S_结构对象指针 命令缓存, S_结构对象指针 fence) {
	S_绘图设备配置* 配置 = ((S_绘图设备配置*)ctx->m_绘图设备配置);

	//auto result = vkResetFences(配置->m_设备, 1, ((VkFence*)&fence));
	auto result = vkResetCommandBuffer((VkCommandBuffer)命令缓存, 0);
	assert(result == VK_SUCCESS);

	VkCommandBufferBeginInfo cmdBufferBeginInfo{};
	cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
	
	

	result = vkBeginCommandBuffer((VkCommandBuffer)命令缓存, &cmdBufferBeginInfo);
	assert(result == VK_SUCCESS);
}

void f_Draw_end(S_设备环境* ctx, S_结构对象指针 命令缓存, S_结构对象指针 fence, uint8 列队) {
	S_绘图设备配置* 配置 = ((S_绘图设备配置*)ctx->m_绘图设备配置);

	auto result = vkEndCommandBuffer((VkCommandBuffer)命令缓存);
	assert(result == VK_SUCCESS);

	VkSubmitInfo 命令提交信息{ VK_STRUCTURE_TYPE_SUBMIT_INFO };
	命令提交信息.commandBufferCount = 1;
	命令提交信息.pCommandBuffers = (VkCommandBuffer*)&命令缓存;
	result = vkQueueSubmit(配置->m_图形列队[列队], 1, &命令提交信息, (VkFence)fence);
	//result = vkQueueSubmit(配置->m_图形列队[列队], 1, &命令提交信息, 配置->m_同步围栏);
	//result = vkQueueSubmit(配置->m_图形列队[列队], 1, &命令提交信息, VK_NULL_HANDLE);
	//result = vkQueueWaitIdle(配置->m_图形列队[列队]);
	//vkDeviceWaitIdle(配置->m_设备);
	//return;

	assert(result == VK_SUCCESS);
	do {
		result = vkWaitForFences(配置->m_设备, 1, (VkFence*)&fence, VK_TRUE, FENCE_TIMEOUT);
		//result = vkWaitForFences(配置->m_设备, 1, (VkFence*)&配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	result = vkResetFences(配置->m_设备, 1, ((VkFence*)&fence));
	assert(result == VK_SUCCESS);
	//vkResetFences(配置->m_设备, 1, ((VkFence*)&配置->m_同步围栏));
	//vkDestroyFence(配置->m_设备, fence, nullptr);
}





void f_Draw_构建顶层加速结构(S_设备环境* ctx, S_帧缓存* frame, uint8 id) {
	auto 配置 = f_vk_get绘图环境(*ctx);
	
	auto mat = f_mat34_identity();
	auto* 光追实例 = f_buf_create板载缓存(*ctx, sizeof(VkAccelerationStructureInstanceKHR), E_板载缓存类型::e_光追实例, 1);
	auto ptr_instance = f_buf_map板载缓存<VkAccelerationStructureInstanceKHR>(光追实例);
	ptr_instance[0].transform = *((VkTransformMatrixKHR*)&mat);
	ptr_instance[0].instanceCustomIndex = 0;
	ptr_instance[0].mask = 0xFF;
	ptr_instance[0].instanceShaderBindingTableRecordOffset = 0;
	ptr_instance[0].flags = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
	//instance.accelerationStructureReference = bottomLevelAS.deviceAddress;
	f_buf_unmap板载缓存(光追实例);

	
	uint32 物体数量 = 1;
	std::vector<VkAccelerationStructureGeometryKHR> 几何加速结构;
	for (uint32 i = 0; i < 物体数量; ++i) {
		VkAccelerationStructureGeometryKHR asg{ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR }; {
			asg.geometryType = VK_GEOMETRY_TYPE_INSTANCES_KHR;
			asg.flags = VK_GEOMETRY_OPAQUE_BIT_KHR;
			asg.geometry.instances.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR;
			asg.geometry.instances.arrayOfPointers = VK_FALSE;
			VkDeviceOrHostAddressConstKHR 实例数据{};
			实例数据.deviceAddress = f_buf_getAddress(static_cast<S_VkArray缓存*>(光追实例));
			asg.geometry.instances.data = 实例数据;
		}
		几何加速结构.push_back(asg);
	}
	
	

	VkAccelerationStructureBuildGeometryInfoKHR 加速结构绑定几何信息{ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR };
	加速结构绑定几何信息.type = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR;
	加速结构绑定几何信息.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
	加速结构绑定几何信息.geometryCount = 几何加速结构.size();
	加速结构绑定几何信息.pGeometries = 几何加速结构.data();


	uint32_t primitive_count = 1;
	VkAccelerationStructureBuildSizesInfoKHR accelerationStructureBuildSizesInfo{ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR };
	配置->vkGetAccelerationStructureBuildSizes(
		配置->m_设备,
		VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,
		&加速结构绑定几何信息,
		&primitive_count,
		&accelerationStructureBuildSizesInfo);

	auto as = f_buf_create板载缓存(*ctx, 1, E_板载缓存类型::e_光追顶层加速结构, accelerationStructureBuildSizesInfo.accelerationStructureSize);
	

	//在构建顶级加速结构期间创建一个小的暂存缓冲区
	auto* 暂存缓冲区 = f_buf_create板载缓存(*ctx, 1, E_板载缓存类型::e_SSBO, accelerationStructureBuildSizesInfo.accelerationStructureSize);


	加速结构绑定几何信息.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
	加速结构绑定几何信息.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR;
	加速结构绑定几何信息.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
	加速结构绑定几何信息.dstAccelerationStructure = f_buf_get加速结构(as);
	加速结构绑定几何信息.scratchData.deviceAddress = f_buf_getAddress(static_cast<S_VkArray缓存*>(暂存缓冲区));


	VkAccelerationStructureBuildRangeInfoKHR 绑定偏移信息{};
	VkAccelerationStructureBuildRangeInfoKHR* ptr_绑定偏移信息 = &绑定偏移信息;
	VkBufferDeviceAddressInfo 缓存信息{ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO };
	

	
	配置->vkCmdBuildAccelerationStructures(配置->m_命令缓存, 1, &加速结构绑定几何信息, &ptr_绑定偏移信息);

}




void f_Draw2D多边形(S_设备环境& ctx, S_渲染参数& 渲染参数, bool 是否填充) {

}







S_GPU计算* f_gpu_create并行计算实例(S_设备环境& ctx, std::string path, const std::vector<S_着色器创建参数>& 参数配置, const std::vector<S_着色器常量推送创建参数>& 常量) {
	S_GPU计算* mat = new S_GPU计算(&ctx);
	S_线管创建配置 图元配置 = {
		{
			参数配置
		},
		{ },
		{
			{path, E_着色阶段::e_计算着色},
		},
		{
			常量
		}
	};

	mat->m_Ctx = ctx;
	mat->m_Shader = f_create着色(ctx, 图元配置);
	mat->m_Pipeline = f_Gpu_create计算线管(ctx, *mat->m_Shader);
	mat->m_Shader->f_alloc参数设置(&(mat->m_GPU参数set));
	return mat;
}




bool f_device_是否支持光追(const S_设备& dev) {
	if (((const S_物理设备属性*)(dev.物理设备.pNext))->m_支持光追) {
		return true;
	}
	return false;
}

bool f_device_是否支持光追(const S_协处理设备& dev) {
	if (((const S_物理设备属性*)(dev.pNext))->m_支持光追) {
		return true;
	}
	return false;
}





















/*void f_Draw_Begin(S_结构对象指针 命令缓存, S_设备环境* 绘图配置, S_帧缓存* frame, uint8 id) {
	VkResult result;

	//S_绘图设备配置* 配置 = ((S_绘图设备配置*)绘图配置->m_逻辑设备.pNext);
	S_绘图设备配置* 配置 = ((S_绘图设备配置*)绘图配置->m_绘图设备);


	result = vkResetCommandBuffer((VkCommandBuffer)命令缓存, 0);
	assert(result == VK_SUCCESS);
	result = vkBeginCommandBuffer((VkCommandBuffer)命令缓存, &配置->m_命令开始信息);
	assert(result == VK_SUCCESS);

	S_Vk帧缓存* 帧 = static_cast<S_Vk帧缓存*>(frame);
	配置->m_开始渲染信息.framebuffer = 帧->m_帧缓存[id];
	配置->m_开始渲染信息.renderPass;

	配置->m_开始渲染信息.renderArea.extent.width = frame->m_Size.x;
	配置->m_开始渲染信息.renderArea.extent.height = frame->m_Size.y;
	//result = vkResetCommandBuffer(配置->m_命令缓存, 0);									//恢复命令缓冲到初始状态  帧->m_帧缓存[id]
	//result = vkBeginCommandBuffer(配置->m_命令缓存, &配置->m_二级渲染开始信息);	//启动命令缓冲

	vkCmdBeginRenderPass((VkCommandBuffer)命令缓存, &配置->m_开始渲染信息, VK_SUBPASS_CONTENTS_INLINE);

}

void f_Draw_end(S_结构对象指针 命令缓存, S_设备环境* 绘图配置) {
	S_绘图设备配置* 配置 = ((S_绘图设备配置*)绘图配置->m_绘图设备);

	vkCmdEndRenderPass((VkCommandBuffer)命令缓存);

	auto result = vkEndCommandBuffer((VkCommandBuffer)命令缓存);
	assert(result == VK_SUCCESS);

	//VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
	result = vkQueueSubmit(配置->m_图形列队[配置->m_列队ID], 1, &(配置->m_命令提交信息), 配置->m_同步围栏);
	assert(result == VK_SUCCESS);

	do {
		result = vkWaitForFences(配置->m_设备, 1, &配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	vkResetFences(配置->m_设备, 1, &配置->m_同步围栏);
}



void f_Draw_Begin(S_设备环境* ctx, uint8 id) {
	S_绘图设备配置* 配置 = ((S_绘图设备配置*)ctx->m_绘图设备配置);

	VkCommandBufferBeginInfo cmdBufferBeginInfo{};
	cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;

	//vkResetCommandBuffer(配置->m_命令缓存, 0);
	vkBeginCommandBuffer(配置->m_命令缓存, &cmdBufferBeginInfo);

}

void f_Draw_end(S_设备环境* ctx) {
	S_绘图设备配置* 配置 = ((S_绘图设备配置*)ctx->m_绘图设备配置);

	vkEndCommandBuffer(配置->m_命令缓存);
	auto result = vkQueueSubmit(配置->m_图形列队[配置->m_列队ID], 1, &(配置->m_命令提交信息), 配置->m_同步围栏);

	do {
		result = vkWaitForFences(配置->m_设备, 1, &配置->m_同步围栏, VK_TRUE, FENCE_TIMEOUT);
	} while (result == VK_TIMEOUT);
	vkResetFences(配置->m_设备, 1, &配置->m_同步围栏);
}*/











